package eerbaar.action.internal.lib;

import eerbaar.action.internal.lib.position.IPositionGenerator;
import eerbaar.action.internal.lib.position.PositionGeneratorFactory;
import eerbaar.area.IArea;
import eerbaar.elements.IElement;
import eerbaar.game.IGame;
import eerbaar.position.IPosition;
import eerbaar.position.PositionFactory;

public class Global {

    public enum Corner {
        UpperLeft, UpperRight, LowerRight, LowerLeft
    };

    private static Corner corner = Corner.LowerLeft;

    public static IPosition calcInputPosition(String position, IArea area) {

        if (position == null) {
            return null;
        }
        if (!position.contains(",")) {
            return null;
        }

        String work = position.replace('(', ' ');
        work = work.replace(')', ' ');
        work = work.trim();

        String[] parts = work.split(",");
        String part1 = parts[0];
        String part2 = parts[1];

        int x = Integer.parseInt(part1);
        int y = Integer.parseInt(part2);

        if (x < 0 || x > 9) {
            return null;
        }
        if (y < 0 || y > 9) {
            return null;
        }

        IPosition p = PositionFactory.createPosition(x, y);

        IElement[] elements = area.getElements(p);
        if (elements.length > 0) {
            return null;
        }

        return p;
    }

    public static IPosition calcPosition(IGame game, IArea area, String position) {

        return calcPosition(game, area, position, true);
    }

    public static IPosition calcPosition(IGame game, IArea area,
            String position, boolean checkIsOccupied) {

        if (position == null) {
            return null;
        }

        IPosition p = parseInputPosition(position, area, checkIsOccupied);
        if (p != null) {
            return p;
        }

        return calcRandomPosition(game, area);
    }

    public static IPosition calcRandomPosition(IGame game, IArea area) {

        IPosition p = null;
        int watchdog = 0;
        for (int i = 0; i < 100; i++, watchdog++) {

            if (watchdog > 1000) {
                break;
            }

            IPositionGenerator g = PositionGeneratorFactory.createRandom();
            p = g.next(game);
            if (p == null) {
                continue;
            }

            IElement[] elements = area.getElements(p);
            if (elements.length > 0) {
                continue;
            }

            break;
        }

        return p;
    }

    private static IPosition parseCorner(String position) {

        IPosition p = null;

        if (position.contains("corner")) {

            if (corner == Corner.LowerLeft) {
                corner = Corner.UpperLeft;
                p = PositionFactory.createPosition(0, 9);
            } else if (corner == Corner.UpperLeft) {
                corner = Corner.UpperRight;
                p = PositionFactory.createPosition(0, 0);
            } else if (corner == Corner.UpperRight) {
                corner = Corner.LowerRight;
                p = PositionFactory.createPosition(9, 0);
            } else if (corner == Corner.LowerRight) {
                corner = Corner.LowerLeft;
                p = PositionFactory.createPosition(9, 9);
            }
        }

        return p;
    }

    public static IPosition parseInputPosition(String position, IArea area) {

        return parseInputPosition(position, area, true);
    }

    public static IPosition parseInputPosition(String position, IArea area,
            boolean checkIsOccupied) {

        IPosition p = parseCorner(position);
        if (p == null) {
            p = calcInputPosition(position, area);
        }
        if (p == null) {
            return null;
        }

        if (checkIsOccupied) {
            IElement[] elements = area.getElements(p);
            if (elements.length > 0) {
                return null;
            }
        }

        return p;
    }
}
